/*
 * Tank.cpp
 *
 *  Created on: 06.10.2013
 *      Author: dima
 */

#include "../Globals.hpp"

#include "TankView.hpp"

#include "../Resources/SoundLoader.hpp"

#include "../Model/MissileModel.hpp"
#include "../Model/Types.hpp"

#include <iostream>



Tanks::
View::
TankView::
TankView(Tanks::Model::TankModel * argTankModel,
     SDL_Surface * argScreen) :
       m_tankModel(argTankModel),
       m_screen(argScreen),
       m_XOffsetTank(15),
       m_YOffsetTank(15),
       m_currentImg(0),
       m_currentExplosionImg(0)
{
  Resources::IMGLoader & imgLoader = Resources::IMGLoader::getInstance();
  Tanks::Model::GameObjectType type = m_tankModel->GetType();
  switch(type)
  {
  case Tanks::Model::Player:
    m_tankImage = imgLoader.GetImage(Resources::Player);
    break;
  case Tanks::Model::TankEasy:
    m_tankImage = imgLoader.GetImage(Resources::TankEasy);
    break;
  case Tanks::Model::TankMedium:
    m_tankImage = imgLoader.GetImage(Resources::TankMedium);
    break;
  case Tanks::Model::TankHard:
    m_tankImage = imgLoader.GetImage(Resources::TankHard);
    break;
  default:
    throw std::string("Invalid tank type");
    break;
  }
  m_tankExplosionImage = imgLoader.GetImage(Resources::ExplosionTank);
  if(m_tankImage == 0 || m_tankExplosionImage == 0)
  {
    throw std::string("An image is not loaded");
  }

  Resources::SoundLoader & soundLoader = Resources::SoundLoader::getInstance();
  m_shootSoundChannel = soundLoader.GetFreeChannel();
  Mix_Volume(m_shootSoundChannel, 90);
  m_driveSoundChannel = soundLoader.GetFreeChannel();
  Mix_Volume(m_driveSoundChannel, 80);
  m_idleSoundChannel = soundLoader.GetFreeChannel();
  Mix_Volume(m_idleSoundChannel, 40);
  m_tankExplosionSoundChannel = soundLoader.GetFreeChannel();
  Mix_Volume(m_tankExplosionSoundChannel, 128);
}


Tanks::
View::
TankView::
~TankView()
{
  Resources::SoundLoader & soundLoader = Resources::SoundLoader::getInstance();
  soundLoader.FreeChannel(m_shootSoundChannel);
  soundLoader.FreeChannel(m_driveSoundChannel);
  soundLoader.FreeChannel(m_idleSoundChannel);
  soundLoader.FreeChannel(m_tankExplosionSoundChannel);
}


#include <iostream>
void
Tanks::
View::
TankView::
Draw()
{
  PlaySounds();
  if(!m_tankModel->IsAlive())
  { return; }
  if(m_tankModel->IsExploding())
  { DrawTankExplosion(); }

  Resources::IMGSplitter & imgSplitter = Resources::IMGSplitter::getInstance();

  Tanks::Model::Direction direction = m_tankModel->GetDirection();
  std::vector<SDL_Rect> rects = imgSplitter.Animations[direction];
  // animate only if moving
  if(m_tankModel->IsMoving())
  {
    m_currentImg = (m_currentImg + 1) % rects.size();
  }
  SDL_Rect frame = rects[m_currentImg];

  SDL_Rect * rect = m_tankModel->GetRect();
  SDL_Rect tankOffset;
  tankOffset.x = rect->x - m_XOffsetTank;
  tankOffset.y = rect->y - m_YOffsetTank;

  SDL_BlitSurface(m_tankImage, &frame, m_screen, &tankOffset);
}



void
Tanks::
View::
TankView::
DrawTankExplosion()
{
  Resources::IMGSplitter & imgSplitter = Resources::IMGSplitter::getInstance();
  std::vector<SDL_Rect> explosionTankRects = imgSplitter.Animations[Tanks::Resources::ExplosionTankAnimation];
  SDL_Rect frame = explosionTankRects[m_currentExplosionImg];
  SDL_Rect offset;
  offset.x = m_tankModel->GetRect()->x - m_XOffsetTank - 10;
  offset.y = m_tankModel->GetRect()->y - m_YOffsetTank - 10;
  SDL_BlitSurface(m_tankExplosionImage,
          &frame,
          m_screen,
          &offset);
  m_currentExplosionImg = (m_currentExplosionImg + 1) % explosionTankRects.size();
}


void
Tanks::
View::
TankView::
PlaySounds()
{
  Resources::SoundLoader & soundLoader = Resources::SoundLoader::getInstance();

  if(m_tankModel->IsShooting())
  {
    Mix_PlayChannel(m_shootSoundChannel, soundLoader.GetSound(Resources::ShootSound), 0);
  }
  if(m_tankModel->IsExploding())
  {
    if(!Mix_Playing(m_tankExplosionSoundChannel))
    {
      Mix_PlayChannel(m_tankExplosionSoundChannel, soundLoader.GetSound(Resources::TankExplosionSound), 0);
    }
  }

  if(!m_tankModel->IsAlive())
  {
    Mix_HaltChannel(m_idleSoundChannel);
    Mix_HaltChannel(m_driveSoundChannel);
  }
  else if(m_tankModel->IsMoving())
  {
    if(!Mix_Playing(m_driveSoundChannel))
    {
      Mix_PlayChannel(m_driveSoundChannel, soundLoader.GetSound(Resources::DriveSound), -1);
    }
    Mix_HaltChannel(m_idleSoundChannel);
  }
  else
  {
    if(!Mix_Playing(m_idleSoundChannel))
    {
      Mix_PlayChannel(m_idleSoundChannel, soundLoader.GetSound(Resources::IdleSound), -1);
    }
    Mix_HaltChannel(m_driveSoundChannel);
  }
}


